package org.komarichin.struts2;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.I18nInterceptor;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.komarichin.Configurator;
import org.komarichin.Constants;
import org.komarichin.beans.IArticle;
import org.komarichin.beans.ILanguage;
import org.komarichin.beans.INews;
import org.komarichin.beans.seo.ISeo;
import org.komarichin.beans.service.*;
import org.komarichin.feed.IEntryFeed;
import org.komarichin.feed.IFeedWriter;
import org.komarichin.google.IGoogleService;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: mikom
 * Date: 19.09.2009
 * Time: 21:02:10
 */
public class BaseAction extends ActionSupport {
    private static final long serialVersionUID = 4707496434599619505L;


    private static final String cookies = ";jsessionid";


    private String pageTitle = StringUtils.EMPTY;
    private String pageDescription = StringUtils.EMPTY;
    private String pageKeyWords = StringUtils.EMPTY;
    private String pageExpire = StringUtils.EMPTY;
    private String newLanguage;

    @Autowired
    private IPartitionService<Long> partitionService;
    @Autowired
    private INewsService<Long> newsService;
    @Autowired
    private IArticleService<Long> articleService;
    @Autowired
    private IGoogleService googleService;
    @Autowired
    private ILanguageService<Long> languageService;
    @Autowired
    private IFeedWriter feedWriter;
    @Autowired
    private ICommentService<String> commentService;
    @Autowired
    private Configurator configurator;

    /**
     * variable has to be rss or atom
     */
    private String feedType = IFeedWriter.FEED_TYPE_ATOM;

    public String getFeed() throws Exception {
        List<IEntryFeed> l = new ArrayList<IEntryFeed>();
        String basePath = configurator.getServerBasePath();

        for (IArticle<Long> n : articleService.getLatestArticles()) {
            if (n != null) {
                n.setLink(basePath + "/article/view?article.id=" + n.getId());
                l.add(n);
            }
        }
        for (INews<Long> n : newsService.getLatestNews()) {
            if (n != null) {
                n.setLink(basePath + "/news/view?news.id=" + n.getId());
                l.add(n);
            }
        }
        Collections.sort(l, new Comparator<IEntryFeed>() {

            @Override
            public int compare(IEntryFeed iEntryFeed, IEntryFeed iEntryFeed1) {
                return (int) (iEntryFeed1.getUpdate().getTime() - iEntryFeed.getUpdate().getTime());
            }
        });
        String result;
        if (IFeedWriter.FEED_TYPE_RSS.equals(feedType)) {
            result = feedWriter.getFeeds("Komarichyn's home page", "/index", "Latest event", "rss_2.0", l);
        } else {
            result = feedWriter.getFeeds("Komarichyn's home page", "/index", "Latest event", "atom_0.3", l);
        }
        return result;
    }

    public boolean isAtomFeed() {
        return IFeedWriter.FEED_TYPE_ATOM.equals(feedType);
    }

    public String getFeedContentType() {
        if (IFeedWriter.FEED_TYPE_RSS.equals(feedType)) {
            return "application/rss+xml";
        } else {
            return "application/atom+xml";
        }
    }


    public String changeLanguage() throws Exception {
        Locale locale = new Locale(newLanguage);
        ActionContext.getContext().setLocale(locale);
        Map<String, Object> session = ActionContext.getContext().getSession();
        session.put(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE, locale);
        session.put("javax.servlet.jsp.jstl.fmt.locale.session", locale);
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        String referer = request.getHeader("referer");
        if (StringUtils.isNotEmpty(referer)) {
            response.sendRedirect(reformatURL(referer, newLanguage));
        }

        return null;
    }

    public String reformatURL(String referer, String ext) {
        int index = referer.indexOf("?");
        if (index != -1) {
            int dotIndex = referer.substring(0, index).lastIndexOf(".");
            int slashIndex = referer.substring(0, index).lastIndexOf("/");
            if (slashIndex > dotIndex) dotIndex = -1;
            if (dotIndex != -1) {
                return referer.substring(0, dotIndex) + "." + ext + referer.substring(index, referer.length());
            } else {
                referer = referer.substring(0, index).split(cookies)[0] + referer.substring(index, referer.length());
                index = referer.indexOf("?");
                return referer.substring(0, index) + "." + ext + referer.substring(index, referer.length());
            }
        } else {
            referer = referer.split(cookies)[0];
            int dotIndex = referer.lastIndexOf(".");
            int slashIndex = referer.lastIndexOf("/");
            if (slashIndex > dotIndex) dotIndex = -1;
            if (dotIndex != -1) {
                return referer.substring(0, dotIndex) + "." + ext;
            } else {
                return referer + "." + ext;
            }
        }
    }


    public String getUserLanguage() {
        Map<String, Object> session = ActionContext.getContext().getSession();
        Object l = session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE);
        if (l == null || !(l instanceof Locale)) return StringUtils.EMPTY;
        else return ((Locale) l).getLanguage();
    }

    public ILanguage<Long> getLanguage() {
        Map<String, Object> session = ActionContext.getContext().getSession();
        Object l = session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE);
        return l != null ? languageService.findByName(((Locale) l).getLanguage()) : null;
    }

    public String getLangById(Long id) {
        if (id == 0) return StringUtils.EMPTY;
        ILanguage<Long> l = languageService.findById(id);
        return l == null ? StringUtils.EMPTY : l.getIsoName();
    }

    @Override
    public String execute() throws Exception {
        return super.execute();
    }

    public Collection<ILanguage<Long>> getLanguages() {
        Collection<ILanguage<Long>> ls = languageService.getAll();

        //hardCode
        if (ls == null || ls.size() < 2) {
            ls = new ArrayList<ILanguage<Long>>();
            ILanguage<Long> l = languageService.findByName("ru");
            if (l == null) {
                l = languageService.newInstance();
                l.setIsoName("ru");
                l = languageService.save(l);
                ls.add(l);
            }
            l = languageService.findByName("en");
            if (l == null) {
                l = languageService.newInstance();
                l.setIsoName("en");
                l = languageService.save(l);
                ls.add(l);
            }

        }
        return ls;
    }

    public String getPageTitle() {
        return pageTitle;
    }

    public String getPageDescription() {
        return pageDescription;
    }

    public String getPageKeyWords() {
        return pageKeyWords;
    }

    public void setPageTitle(String pageTitle) {
        this.pageTitle = pageTitle;
    }

    public void setPageDescription(String pageDescription) {
        this.pageDescription = pageDescription;
    }

    public void setPageKeyWords(String pageKeyWords) {
        this.pageKeyWords = pageKeyWords;
    }

    public String getPageExpire() {
        return pageExpire;
    }

    public void setPageExpire(String pageExpire) {
        this.pageExpire = pageExpire;
    }


    public String getRequestParamByName(String name) {
        return ServletActionContext.getRequest().getParameter(name);
    }

    public INewsService<Long> getNewsService() {
        return newsService;
    }

    public IGoogleService getUserService() {
        return googleService;
    }

    public void setUserService(IGoogleService googleService) {
        this.googleService = googleService;
    }

    public IGoogleService getGoogleService() {
        return getUserService();
    }

    public String getLogoutURL() {
        return StringEscapeUtils.unescapeXml(googleService.createLogoutURL(ActionContext.getContext().getSession().get(Constants.FULL_REQ_PATH).toString()));
    }

    public String getLoginURL() {
        return StringEscapeUtils.unescapeXml(googleService.createLoginURL(ActionContext.getContext().getSession().get(Constants.FULL_REQ_PATH).toString()));
    }

    public IPartitionService<Long> getPartitionService() {
        return partitionService;
    }

    public void setPartitionService(IPartitionService<Long> partitionService) {
        this.partitionService = partitionService;
    }

    public ILanguageService<Long> getLanguageService() {
        return languageService;
    }

    public void setLanguageService(ILanguageService<Long> languageService) {
        this.languageService = languageService;
    }

    public void defineMetaTags(ISeo seo) {
        setPageTitle(seo.getTitle());
        setPageDescription(seo.getDescription());
        setPageKeyWords(seo.getKeyWords());
        if (seo.getUpdate() != null)
            setPageExpire(seo.getUpdate().toString());
        else setPageKeyWords(StringUtils.EMPTY);
    }

    public String getNewLanguage() {
        return newLanguage;
    }

    public void setNewLanguage(String newLanguage) {
        this.newLanguage = newLanguage;
    }

    public IArticleService<Long> getArticleService() {
        return articleService;
    }

    public void setArticleService(IArticleService<Long> articleService) {
        this.articleService = articleService;
    }

    public ICommentService<String> getCommentService() {
        return commentService;
    }

    public void setCommentService(ICommentService<String> commentService) {
        this.commentService = commentService;
    }

    public IFeedWriter getFeedWriter() {
        return feedWriter;
    }

    public void setFeedWriter(IFeedWriter feedWriter) {
        this.feedWriter = feedWriter;
    }

    public String getFeedType() {
        return feedType;
    }

    public void setFeedType(String feedType) {
        this.feedType = feedType;
    }

    public Configurator getConfigurator() {
        return configurator;
    }

    public void setConfigurator(Configurator configurator) {
        this.configurator = configurator;
    }
}
